import Taro from '@tarojs/taro';
import shortid from 'js-shortid';
import config from '@/env/config';
import { ILocationData, IDriving, IDrivingPath, ICityInfo, IToastContentOption } from '@/types';
import Storage from './storage';
import ParamsUtil from './params';
import catchError from './catchError';

/**
 * @private
 * 是否是哈啰内部的H5链接
 * @param {string} url
 * @return {boolean}
 */
export function isH5Link(url: string): boolean {
  return /^(http|https):\/\/m\.aunt\.geekbuluo\.com/.test(url);
}

class AliCallNative {
  /**
   * 显示一个弱提示，可选择多少秒之后消失
   * 可以传入错误对象，错误对象统一提示＂发生错误，请稍后重试＂，并且自动走ubt上报
   * @param {string|TypeError|IToastContentOption} content
   * @param options
   * @param [options.duration=2000] - 显示时长，单位为 ms，默认 2000
   * @param [options.complete] - 调用结束的回调函数（调用成功、失败都会执行）
   * @param [options.type] - toast类型，展示相应图标，默认none，- 'success': 显示成功图标，此时 title 文本最多显示 7 个汉字长度;
   * - 'loading': 显示加载图标，此时 title 文本最多显示 7 个汉字长度;
   * - 'none': 不显示图标，此时 title 文本最多可显示两行
   * @return {Promise}
   * @see https://taro-docs.jd.com/taro/docs/apis/ui/interaction/showToast
   */
  static showToast(
    content: string | IToastContentOption,
    options = {}
  ): Promise<Taro.General.CallbackResult | void> {
    let title;
    if (!content) {
      return Promise.resolve();
    }
    if (content && typeof content === 'object' && content.message) {
      if (content instanceof Error) {
        // store.dispatch({
        //   type: 'error/add',
        //   payload: content
        // });
        if (content.name === 'SystemError') {
          return Promise.resolve();
        }
      }

      if (content.name === 'TypeError') {
        title = '发生错误，请稍后重试';
      } else {
        title = content.message;
      }
    } else if (typeof content === 'string') {
      title = content;
    } else {
      return Promise.resolve();
    }

    return Taro.showToast({
      title,
      duration: 2000,
      ...options,
    });
  }

  /**
   * 显示Loading提示
   * @param {string} [content=加载中] - 提示内容
   * @param {boolean} [noDelay=1000] - 延时等待显示的时间
   * @return {Promise}
   */
  static showLoading(
    title = '加载中',
    defaultOptions?: {
      mask: boolean;
      noDelay: number;
    }
  ): void {
    const options = Object.assign(
      {
        mask: false,
        noDelay: 1000,
      },
      defaultOptions
    );
    Taro.showLoading({
      mask: options.mask,
      title,
    });
    setTimeout(
      () => {
        Taro.hideLoading();
      },
      options.noDelay ? options.noDelay : 1000
    );
  }

  /**
   * 隐藏Loading提示, 如果存在loading的定时任务会清除掉
   * @return {Promise}
   */
  static hideLoading(): void {
    return Taro.hideLoading();
  }

  /**
   * 保留当前页面，跳转到应用内的某个指定页面
   * @param {string} url
   * @return {Promise}
   * @link https://taro-docs.jd.com/taro/docs/apis/route/navigateTo
   */
  static navigateTo(url: string): Promise<Taro.General.CallbackResult> {
    const pages = Taro.getCurrentPages();
    const beyond = pages && pages.length >= 5;
    return Taro[beyond ? 'redirectTo' : 'navigateTo']({
      url: url.indexOf('/') === 0 ? url : `/${url}`,
    });
  }

  /**
   * 跳转到指定 tabBar 页面，并关闭其他所有非 tabBar 页面
   * @private
   * @param {string} url - 跳转的 tabBar 页面的路径（需在 app.json 的 tabBar 字段定义的页面）。注意：路径后不能带参数
   * @return {Promise}
   * @see https://taro-docs.jd.com/taro/docs/apis/route/switchTab
   */
  static switchTab(url: string): Promise<Taro.General.CallbackResult> {
    return Taro.switchTab({
      url: url.indexOf('/') === 0 ? url : `/${url}`,
    });
  }

  /**
   * 关闭当前页面，跳转到应用内的某个指定页面。
   * 备注： 如果url是在tab item中，会自动调用switchTab进行切换
   * @param {string} url
   * @return {Promise}
   * @see https://taro-docs.jd.com/taro/docs/apis/route/redirectTo
   */
  static redirectTo(url: string): Promise<Taro.General.CallbackResult> {
    const isH5 = isH5Link(url);
    if (isH5) {
      return AliCallNative.redirectTo(`/pages/webview/index?url=${encodeURIComponent(url)}`);
    } else {
      return Taro.redirectTo({ url: url.indexOf('/') === 0 ? url : `/${url}` });
    }
  }

  /**
   * 关闭当前所有页面，跳转到应用内的某个指定页面。
   * @param {string} url
   * @return {Promise}
   * @see https://taro-docs.jd.com/taro/docs/apis/base/canIUse
   */
  static reLaunch(url: string): Promise<void | Taro.General.CallbackResult> {
    if (Taro.canIUse('reLaunch')) {
      return Taro.reLaunch({
        url: url.indexOf('/') === 0 ? url : `/${url}`,
      });
    }

    const pages = Taro.getCurrentPages();
    if (pages && pages.length > 1 && url === '/pages/index/index') {
      // 仅处理relauch到首页
      if (pages[0].routerName === 'home') {
        return AliCallNative.navigateBack(pages.length - 1);
      }
      return AliCallNative.navigateBack(pages.length - 1).then(() => {
        setTimeout(() => {
          AliCallNative.redirectTo('/pages/index/index');
        }, 1000);
      });
    }
    return Taro.redirectTo({ url });
  }

  /**
   * 关闭当前页面，返回上一级或多级页面。
   * 可通过 getCurrentPages 获取当前的页面栈信息，决定需要返回几层。
   * @param {number} [delta=1] - 返回的页面数，如果 delta 大于现有打开的页面数，则返回到首页
   * @return {Promise}
   * @see https://taro-docs.jd.com/taro/docs/apis/route/navigateBack
   */
  static navigateBack(delta = 1): Promise<Taro.General.CallbackResult> {
    return Taro.navigateBack({
      delta,
    });
  }

  /**
   * 获取小程序中的ssid
   */
  static getSSID(): string {
    let ssid = Storage.getItemSync('ubt_ssid');
    if (!ssid) {
      const t = new Date(new Date().getTime() + 480 * 60000);
      const shortId = shortid.uuid();
      ssid = `${shortId}_${[t.getUTCFullYear(), t.getUTCMonth() + 1, t.getUTCDate()]
        .join('-')
        .replace(/\b\d\b/g, '0$&')}`;
      Storage.setItem('ubt_ssid', ssid);
    }
    return ssid;
  }
}

export default AliCallNative;
